home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 10 / coppy33.zip / COPPY.C next >
C/C++ Source or Header  |  1988-01-07  |  11KB  |  343 lines

  1. /*
  2. **   COPPY -- Copies files from a DIRLIST to floppy disks
  3. **            fitting as many files by size as it can.
  4. **
  5. **       Thomas A. Lundin
  6. **       Graphics Unlimited Inc.
  7. **       3000 Second Street North
  8. **       Minneapolis, MN 55411
  9. **       (612) 588-7571
  10. **
  11. **    Version 1.0 -- Turbo C
  12. **    11/05/87    version 3.0
  13. **    12/30/87    version 3.1    clean up some of the path calls
  14. **    1/06/88     version 3.2    infinite loop bug fixed
  15. **    1/07/88     version 3.3    added -w switch
  16. **
  17. */
  18.  
  19. #define TRUE 1
  20. #define FALSE 0
  21.  
  22. #include <stdio.h>
  23. #include <ctype.h>
  24. #include <fcntl.h>
  25. #include <dos.h>
  26. #include <dir.h>
  27. #include <io.h>
  28. #include <stdlib.h>
  29. #include <sys\stat.h>
  30.  
  31. char output_file[64];                     /* output file name */
  32. char input_file[64];                      /* input file name */
  33. char fname_buffer[128];                   /* line buffer for gang files */
  34. char *fname_ptr;                          /* ptr for above */
  35.  
  36. char *strings;                            /* where the file names are stored */
  37. char *sptr;                               /* pointer to that area */
  38.  
  39. char *data;                               /* where the file data are stored */
  40. char *dptr;                               /* pointer to that area */
  41.  
  42. int driveno;                              /* dest. drive number */
  43. int fh,fi,fo;                             /* file handles */
  44. int ctrlc();                              /* where CTRL-BREAK goes */
  45.  
  46. FILE *fl;
  47.  
  48. char *names[1200];
  49.  
  50. char s_path[80];                 /* source path */
  51. char s_drv[3];
  52. char s_dir[66];
  53. char s_file[9];
  54. char s_ext[5];
  55.  
  56. char t_path[80];                 /* target path */
  57. char t_drv[3];
  58. char t_dir[66];
  59. char t_file[9];
  60. char t_ext[5];
  61.  
  62. char cur_dir[66];
  63. char s_chdir[66];
  64. char t_chdir[66];
  65.  
  66. struct dfree freespace;
  67. struct ftime ftod;
  68. struct ffblk fcb;
  69.  
  70. main(argc, argv)
  71. int argc;
  72. char *argv[];
  73. {
  74.    int i, j, k;
  75.    long bytesleft;
  76.    long maxspace;
  77.    long minspace;
  78.    long filesize;
  79.    long filetotal = 0L;
  80.    int length;
  81.    int ocount;
  82.    int more = TRUE;
  83.    int mustsort = TRUE;
  84.    int bypass = TRUE;
  85.    char name[13];
  86.  
  87.    ctrlbrk(ctrlc);
  88.  
  89.    if(argc < 3)
  90.       {
  91.       puts("COPPY from HD to FD by largest fit ver.3.3 (c) 1987 Thomas A. Lundin");
  92.       puts("usage:\n    coppy  [d:][\\path\\][filespec]  d:[\\path]  [-u -w]");
  93.       puts("-or-\n    coppy  @dirlist  d:[\\path]  [-u -w]");
  94.       puts("    'dirlist' is a file created by redirecting a DIR command");
  95.       puts("    -u  copies the files in original (unsorted) order");
  96.       puts("    -w  overrides the bypassing of existing files");
  97.       exit(1);
  98.    }
  99.    for (i = 3; (argc-3) > 0; i++, argc--) {    /* process options */
  100.       if (strnicmp(argv[i],"-U",2) == 0) {
  101.          mustsort = FALSE;
  102.          printf("Copy will be in unsorted order\n");
  103.       }
  104.       else if (strnicmp(argv[i],"-W",2) == 0) {
  105.          bypass = FALSE;
  106.          printf("Any existing files will be recopied on new diskettes.\n");
  107.       }
  108.       else {
  109.          printf("\nInvalid option: %s\n",argv[i]);
  110.          exit(1);
  111.       }
  112.    }
  113.  
  114.    getcwd(cur_dir,66);                             /* get current dir */
  115.    fnsplit(argv[1],s_drv,s_dir,s_file,s_ext);      /* split the names */
  116.    fnsplit(argv[2],t_drv,t_dir,t_file,t_ext);
  117.  
  118.    strcpy(s_path,argv[1]);
  119.    strcpy(t_chdir,argv[2]);
  120.  
  121.    driveno = (toupper(*t_drv) - '@');    /* drive number */
  122.  
  123.    if ((strings = malloc(25200)) == NULL) {     /* space for file names */
  124.       printf("Unable to grab string space\n");
  125.       exit(1);
  126.    }
  127.    if ((data = malloc(24576)) == NULL) {        /* space for data */
  128.       printf("Unable to grab data space\n");
  129.       exit(1);
  130.    }
  131.  
  132. /*
  133.                                 The main caller
  134. */
  135.    sptr = strings;
  136.  
  137.    if (*s_file == '@') {
  138.       strcpy(name,s_file+1);           /* form a file.name */
  139.       strcat(name,s_ext);
  140.       if ((fl = fopen(name,"r")) == NULL) {
  141.          printf("Can't open up %s\n",name);
  142.          errorexit(1);
  143.       }
  144.       i = 0;
  145.       while ((fname_ptr = fgets(fname_buffer,128,fl)) != NULL) {
  146.          if ((isalnum(*fname_ptr) || ispunct(*fname_ptr))
  147.          && *fname_ptr != '.' && i < 1200) {
  148.             make_fn(input_file,fname_ptr);
  149.             fi = open(input_file,O_RDONLY);
  150.             filesize = filelength(fi);
  151.             filetotal += filesize;
  152.             sprintf(sptr,"%8.8ld=%s",filesize,input_file);
  153.             names[i] = sptr;
  154.             _close(fi);
  155.             sptr = sptr+strlen(input_file)+9;
  156.             *sptr++ = NULL; /* store terminator, bump pointer */
  157.             ++i;            /* bump array index */
  158.          }
  159.       }
  160.    }
  161.    else {
  162.       for (i = 0; i < 1200; ++i) {
  163.          if (i == 0) {
  164.             if (findfirst(s_path,&fcb,0) == EOF) {
  165.                printf("No files matching %s\n",s_path);
  166.                errorexit(1);
  167.             }
  168.          }
  169.          else {
  170.             if (findnext(&fcb) == EOF) {
  171.                break;
  172.             }
  173.          }
  174.          strcpy(s_path,s_drv);        /* what file to read */
  175.          strcat(s_path,s_dir);
  176.          strcat(s_path,fcb.ff_name);
  177.          fi = open(s_path,O_RDONLY);
  178.          filesize = filelength(fi);
  179.          filetotal += filesize;
  180.          sprintf(sptr,"%8.8ld=%s",filesize,fcb.ff_name);
  181.          names[i] = sptr;
  182.          _close(fi);
  183.          sptr = sptr+strlen(fcb.ff_name)+9;
  184.          *sptr++ = NULL;      /* store terminator, bump pointer */
  185.       }
  186.    }
  187.    if (i >= 1200)
  188.       printf("1200-file maximum. Overrun ignored!\n");
  189.  
  190.    if (mustsort)
  191.       sort(names,i);               /* sort the names in descending size order */
  192.  
  193.    ocount = 0;                   /* how many files have been copied */
  194.    maxspace = 0L;                /* disk capacity */
  195.    while(more) {
  196.       getdfree(driveno,&freespace);       /* free space on floppy */
  197.       if(freespace.df_sclus == EOF) {
  198.          printf("Error in obtaining free space\n");
  199.          errorexit(1);
  200.       }
  201.       bytesleft = (freespace.df_bsec * freespace.df_sclus) * (long )freespace.df_avail;
  202.       maxspace  = (freespace.df_bsec * freespace.df_sclus) * (long )freespace.df_total;
  203.  
  204.       if (filetotal > 0) {
  205.          filesize = filetotal/maxspace;      /* # disks required */
  206.          minspace = filetotal % maxspace;    /* or a fraction thereof */
  207.          if (minspace)
  208.             ++filesize;
  209.          if (filesize == 1)
  210.             strcpy(t_path,".");
  211.          else
  212.             strcpy(t_path,"s.");
  213.          printf("\n%d files will fit on %ld diskette%s\n",i,filesize,t_path);
  214.          printf("\nInsert new disk in drive %c:\nPress any key when ready...\n",driveno + '@');
  215.          getch();
  216.          printf("\n");
  217.          filetotal = 0L;
  218.       }
  219.  
  220.       for (k = 0; k < i; ++k) {     /* for each file in the list */
  221.          if (*(names[k]) == NULL)   /* we've already used this one */
  222.             continue;
  223.          else {
  224.             if ((t_chdir[2] & t_chdir[3]) != NULL) {  /* output subdir used */
  225.                if (access(t_chdir,0) != 0) {      /* need to MKDIR on target? */
  226.                   if (mkdir(t_chdir) == EOF) {
  227.                      printf("Unable to create subdir %s\n",t_chdir);
  228.                      errorexit(1);
  229.                   }
  230.                }
  231.             }
  232.             strcpy(output_file,t_chdir);        /* form the output filespec */
  233.             strcat(output_file,"\\");
  234.             strcat(output_file,names[k]+9);
  235.  
  236.             if (access(output_file,0) == 0) {   /* output already exists */
  237.                if (bypass == TRUE) {
  238.                   *(names[k]) = NULL;
  239.                   ++ocount;
  240.                   printf("%s already exists, and will be bypassed.\n",output_file);
  241.                }
  242.                else {
  243.                   printf("%s already exists, but will be copied later.\n",output_file);
  244.                }
  245.             }
  246.             else {
  247.                if      ((filesize = atol(names[k])) >= bytesleft && mustsort)  continue;  /* file too large */
  248.                else if ((filesize = atol(names[k])) >= bytesleft && !mustsort) break;    /* file too large */
  249.                else {                              /* OK to copy */
  250.                   strcpy(input_file,s_drv);        /* what file to read */
  251.                   strcat(input_file,s_dir);
  252.                   strcat(input_file,names[k]+9);
  253.  
  254.                   if ((fi = open(input_file,O_RDONLY | O_BINARY)) == EOF) {
  255.                      printf("Unable to open input %s\n",input_file);
  256.                      errorexit(1);
  257.                   }
  258.                   getftime(fi,&ftod);                 /* read the tod stamp */
  259.                   if ((fo = open(output_file,O_WRONLY | O_BINARY | O_CREAT, S_IREAD | S_IWRITE)) == EOF) {
  260.                      printf("Can't open output %s\n",output_file);
  261.                      errorexit(1);
  262.                   }
  263.                   printf("-> %s is %ld bytes\n",names[k]+9,filesize);
  264.  
  265.                   while ((length = _read(fi,data,24576)) > NULL)
  266.                      _write(fo,data,length);
  267.  
  268.                   _close(fo);
  269.                   fo = open(output_file, O_RDONLY);         /*  open */
  270.                   setftime(fo,&ftod);                      /*  update time */
  271.                   _close(fo);                              /*  shut */
  272.                   _close(fi);
  273.                   *(names[k]) = NULL;    /* don't use this file again */
  274.                   ++ocount;                       /* output count update */
  275.                   break;
  276.                }
  277.             }
  278.          }
  279.       }
  280.       if (ocount >= i) more = FALSE;
  281.       if (filesize > maxspace) {       /* file size > disk capacity ? */
  282.          printf("\n");
  283.          for (k = 0; k < i; ++k)
  284.             if(*(names[k]) != NULL)
  285.                printf("%s must be split up to fit on a disk.\n",names[k]+9);
  286.          more = FALSE;
  287.       }
  288.       if (filesize > bytesleft || k >= i) {    /* file size > free space ? */
  289.          printf("\nInsert new disk in drive %c:\nPress any key when ready...\n",driveno + '@');
  290.          getch();
  291.          printf("\n");
  292.       }
  293.    }
  294.    chdir(cur_dir);
  295.    exit(0);
  296. }
  297.  
  298. /*
  299.              Make a true file name from a line in the DIRLIST
  300. */
  301. make_fn(name,line)
  302. char *line, *name;
  303. {
  304.     char temp[20];
  305.  
  306.     *name = NULL;                      /* init name buffer */
  307.     stctok(line,temp,20," ");          /* get the name */
  308.     strcat(name,temp);
  309.     strcat(name,".");
  310.     stctok(line+9,temp,20," ");        /* get the extension */
  311.     strcat(name,temp);
  312.     return;
  313. }
  314. /*
  315.             Copy a string up to a terminator character or length
  316. */
  317. stctok(from,to,length,term)
  318. char *from,*to,*term;
  319. int length;
  320. {
  321.    char c;
  322.  
  323. /* The following statement will generate a Turbo C WARNING; pay no attention. */
  324.    while((c = *from++) && (c != *term) && length--)
  325.       *to++ = c;
  326.    *to = NULL;
  327.    return;
  328. }
  329.  
  330. ctrlc()
  331. {
  332.    chdir(cur_dir);
  333.    printf("\nCancelled\n");
  334.    return(0);
  335. }
  336.  
  337. errorexit(n)
  338. int n;
  339. {
  340.    chdir(cur_dir);
  341.    exit(n);
  342. }
  343.